#include <iostream>
#include <cstring>
#include <cassert>

#include "loNetList.hpp"
#include "loScriptMove.hpp"
#include "sisInterface.h"

loScriptMove::loScriptMove()
  : edaMove(), script_(0)
{
  sprintf(scriptDir, ".");
}

loScriptMove::loScriptMove( int script )
  : edaMove(),
    script_(script)
{
  sprintf(scriptDir, ".");
}

loScriptMove::loScriptMove(const loScriptMove &move) 
  : edaMove(move),
    script_(move.script_)
{
  strncpy(scriptDir, move.scriptDir, SCRIPTDIRSIZE);
}

loScriptMove::~loScriptMove()
{
}

edaMove* loScriptMove::clone() const
{
  return new loScriptMove(*this);
}

void loScriptMove::init(const edaSolution &sol)
{
}

double loScriptMove::incrEval(const edaSolution &sol)
{
  // FIXME to improve the performance
  loNetList &mysol = (loNetList&)sol;
  loNetList newsol( mysol );
  update( newsol );
  return newsol.fullEvaluate();
}

void loScriptMove::update( edaSolution &sol ) const
{
  loNetList &mysol = (loNetList &)sol;
  char sfile[256];

  // prepare the script file name
  sprintf( sfile, "%s/move_%d.sis", scriptDir, script_ );
  void *netlist = mysol.getNetlist();
  sisComExecute( netlist, sfile );

  // mark the solution changed
  mysol.setModified();
}

void loScriptMove::Serialize( edaBuffer &buf, bool pack )
{
  edaMove::Serialize( buf, pack );
  int len;

  if ( pack )
  {
    len = strlen(scriptDir);
    buf.Pack( &len, 1);
    buf.Pack( scriptDir, len);
    buf.Pack( &script_, 1 );
  }
  else
  {
    buf.UnPack( &len, 1);
    buf.UnPack( scriptDir, len);
    scriptDir[len] = 0;
    buf.UnPack( &script_, 1 );
  }
}

edaMove& loScriptMove::operator = (const edaMove& move)
{
  loScriptMove &mymove = (loScriptMove&)move;

  script_ = mymove.script_;

  return (*this);
}

bool loScriptMove::operator == (const edaMove &move) const
{
  loScriptMove &mymove = (loScriptMove&)move;
  return script_ == mymove.script_;
}

int loScriptMove::getScript() const
{
  return script_;
}

void loScriptMove::setScript( int script )
{
  script_ = script;
}

void loScriptMove::setScriptDir(const char * _scriptDir)
{
  strncpy(scriptDir, _scriptDir, SCRIPTDIRSIZE);
}

